package com.camartsApp.Util;

import io.jsonwebtoken.Claims;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

/**
 * @version .......
 * @创建时间 2025/6/12  下午11:30
 * @创建者 玉苏甫江
 */
@Component
public class TokenInterceptor implements HandlerInterceptor {

	@Autowired
	private JwtUtils jwtUtils;

	@Autowired
	private RedisUtil redisUtil;

	// token 续期秒数，建议与生成 token 的过期时间保持一致
	private static final long TOKEN_EXPIRE_SECONDS = 60 * 60*24; // 1小时

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

		// 新增：如果请求方法是 OPTIONS，直接放行，不进行 token 验证
		if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
			return true;
		}

		String authHeader = request.getHeader("Authorization");
		String token = extractToken(authHeader);
		response.setContentType("application/json;charset=UTF-8");

		// 1. Token 为空
		if (token == null || token.isEmpty()) {
			response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
			response.getWriter().write("{\"code\":401,\"message\":\"请登录\"}");
			return false;
		}

		// 2. Token 解析
		Claims claims = jwtUtils.getClaimsByToken(token);
		if (claims == null) {
			response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
			response.getWriter().write("{\"code\":401,\"message\":\"请重新登录\"}");
			return false;
		}

		// 3. 获取手机号
		String phone = (String) claims.get("phone");
		if (phone == null) {
			response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
			response.getWriter().write("{\"code\":401,\"message\":\"登陆无效\"}");
			return false;
		}

		// 4. 检查 redis 是否有 token
		String redisKey = "usert:" + phone + ":token";
		String redisToken = redisUtil.get(redisKey);
		if (redisToken == null || !redisToken.equals(token)) {
			response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
			response.getWriter().write("{\"code\":401,\"message\":\"登陆过期，请重新登录\"}");
			return false;
		}

		// 5. 刷新 token 的过期时间（滑动过期）
		redisUtil.expire(redisKey, TOKEN_EXPIRE_SECONDS);

		return true;
	}

	private String extractToken(String authHeader) {
		if (authHeader == null || !authHeader.startsWith("Bearer ")) {
			return null;
		}
		return authHeader.substring(7);
	}
}